package main

import (
	"fmt"
	"io"
	"net/http"
	"runtime"
	"time"
)

func main() {

}

func NumGoroutine() {
	tr := &http.Transport{
		MaxIdleConns:    100,
		IdleConnTimeout: 3 * time.Second,
	}

	for i := 0; i < 5; i++ {
		req, _ := http.NewRequest("GET", "https://www.baidu.com", nil)
		client := &http.Client{
			Transport: tr,
			Timeout:   3 * time.Second,
		}
		resp, err := client.Do(req)
		if resp != nil {
			defer resp.Body.Close()
		}
		if err != nil {
			fmt.Println(err)
			continue
		} else {
			_, _ = io.ReadAll(resp.Body)
			fmt.Println(resp.StatusCode)
		}
	}
	time.Sleep(5 * time.Second)
	fmt.Printf("gorountine num is %d \n", runtime.NumGoroutine())
}

// 因为不关闭body而会导致线程泄露的情况
// 据说不执行close body会导致协程泄露，进而导致内存泄漏。具体情况如何？
func IfNotCloseBody() {
	tr := &http.Transport{
		MaxIdleConns:    100,
		IdleConnTimeout: 3 * time.Second,
	}

	for i := 0; i < 5; i++ {
		req, _ := http.NewRequest("GET", "https://www.baidu.com", nil)
		client := &http.Client{
			Transport: tr,
			// Timeout:   3 * time.Second, // 1 请求不设置超时
		}
		resp, err := client.Do(req)
		if resp != nil {
			// defer resp.Body.Close() // 2 body不显示关闭
		}
		if err != nil {
			fmt.Println(err)
			continue
		} else {
			_, _ = io.ReadAll(resp.Body) // 3 不读取body的内容
			fmt.Println(resp.StatusCode)
		}
	}
	time.Sleep(5 * time.Second)
	fmt.Printf("gorountine num is %d \n", runtime.NumGoroutine())
}
